module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input [3:1] r,   // request
    output [3:1] g   // grant
); 

    /*
    `define STT_W 4
    `define STT_W1 `STT_W - 1

    wire [2:0] ri = r;
    wire [2:0] go;

    reg [`STT_W1:0]   state;
    reg [`STT_W1:0]   nxt_state;

    localparam sidle    = 0;
    localparam sd1      = 1;//devive 1 
    localparam sd2      = 2;
    localparam sd3      = 3;

    // State transition logic (combinational)
    always @(*) begin
        nxt_state[sidle]    <=  (state[sidle] && ~(|ri)) 
                             || (state[sd1]   && ~ri[0]) 
                             || (state[sd2]   && ~ri[1]) 
                             || (state[sd3]   && ~ri[2]);

        nxt_state[sd1  ]    <=  (state[sidle] && ri[0])
                             || (state[sd1  ] && ri[0]);

        nxt_state[sd2  ]    <=  (state[sidle] && ~ri[0] && ri[1])
                             || (state[sd2  ] && ri[1]);

        nxt_state[sd3  ]    <=  (state[sidle] && ~ri[0] && ~ri[1] && ri[2])
                             || (state[sd3  ] && ri[2]);
        
    end

    // State flip-flops (sequential)
    always @(posedge clk ) begin
        if(~resetn)
            state   <=  `STT_W'b1;
        else begin
            state   <=  nxt_state;
        end  
    end

    //output logic
    assign      go[0]   =   state[sd1  ];
    assign      go[1]   =   state[sd2  ];
    assign      go[2]   =   state[sd3  ];
    assign      g       =   go;
    */

    parameter A = 2'd0, B = 2'd1, C = 2'd2, D = 2'd3;  
    reg	[1:0]	current_state;
    reg	[1:0]	next_state;
    
    always@(posedge clk)begin
        if(resetn == 1'b0)begin
            current_state <= A;
        end
        else begin
            current_state <= next_state;
        end
    end
    
    always@(*)begin
        case(current_state)
            A:begin
                if(r[1])begin
                    next_state = B;
                end
                else if(r == 3'd0)begin
                    next_state = A;
                end
                else if(r[2:1] == 2'd2)begin
                    next_state = C;
                end
                else if(r == 3'd4)begin
                    next_state = D;
                end
                else begin
                    next_state = A;
                end
            end
            B:begin
                if(r[1])begin
                    next_state = B;
                end
                else if(r[1] == 1'b0)begin
                    next_state = A;
                end
                else begin
                    next_state = A;
                end
            end
            C:begin
                if(r[2])begin
                    next_state = C;
                end
                else if(r[2] == 1'b0)begin
                    next_state = A;
                end
                else begin
                    next_state = A;
                end
            end
            D:begin
                if(r[3])begin
                    next_state = D;
                end
                else if(r[3] == 1'b0)begin
                    next_state = A;
                end
                else begin
                    next_state = A;
                end
            end
            default:begin
                next_state = A;
            end
        endcase
    end
    
    always@(*)begin
        if(current_state == B)begin
            g[1] = 1'b1;
        end
        else begin
            g[1] = 1'b0;
        end
        if(current_state == C)begin
            g[2] = 1'b1;
        end
        else begin
            g[2] = 1'b0;
        end
        if(current_state == D)begin
            g[3] = 1'b1;
        end
        else begin
            g[3] = 1'b0;
        end
    end

endmodule
